/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package checkers.web;

import checkers.constants.web.WebPages;
import checkers.businessLogic.GameManager;
import checkers.businessLogic.game.Game;
import checkers.businessLogic.game.Piece;
import checkers.businessLogic.game.Position;
import checkers.constants.freemarker.Tags;
import checkers.constants.web.SessionAttributes;
import checkers.exceptions.EmailNotFoundException;
import checkers.exceptions.RequestNotAllowedException;
import com.google.gson.Gson;
import freemarker.template.Configuration;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 *
 * @author artinshahverdian
 */
public class GameOperationsViewGenerator {

    //private int i;
    private Configuration configuration = null;
    private GameManager gameManager = null;
    UserOperationsViewGenerator userOperationsViewGenerator;

    public GameOperationsViewGenerator(Configuration configuration) throws Exception {
        this.configuration = configuration;
        gameManager = GameManager.getInstance();
        userOperationsViewGenerator = new UserOperationsViewGenerator(configuration);
    }

    public String getGameTablesJsonObject() {



        Gson gson = new Gson();

        LinkedList<Game> gameTables = gameManager.getGameTables();
        String result = gson.toJson(gameTables);
        return result;


    }

    public boolean createGameTable(HttpServletRequest request, String userId, String gameTableName) throws SQLException {
        Map map = new HashMap();
        HttpSession session = request.getSession();
        if (!isGuest(request)) {

            if (gameManager.addGame(userId, gameTableName)) {

                session.setAttribute(SessionAttributes.GAME_TABLE_NAME, gameTableName);
                return true;
            }
            else {
                return false;
            }

        }
        return false;
    }

    public boolean joinTable(String userId, String tableName, HttpServletRequest request) throws SQLException {



        boolean success = false;

        success = gameManager.joinTable(userId, tableName);


        return success;





    }

    public String getGameTableJSON(String tableName) {


        Game game = gameManager.getGameTableByName(tableName);
        Gson gson = new Gson();

        return gson.toJson(game);

    }

    public String makeMove(Position from, Position to, String gameTableName) throws SQLException, Exception {

        Game game = gameManager.makeMove(from, to, gameTableName);
        Gson gson = new Gson();
        return gson.toJson(game);

    }

    public void deleteTable(String gameTableName) {
        gameManager.deleteTable(gameTableName);
    }

    public View getGameTable(String tableName, HttpServletRequest request) throws RequestNotAllowedException {
        String userId = getSessionUserId(request);
        Game game = gameManager.getGameTableByName(tableName);
        String player1 = game.getPlayer1().getName();
        String player2 = game.getPlayer2().getName();
        Map map = new HashMap();
        map.put(Tags.PLAYER1_NAME, player1);
        map.put(Tags.PLAYER2_NAME, player2);
        if (isUserGameCreator(tableName, request)) {
            map.put(Tags.GAME_TABLE_NAME, tableName);
            map.put(Tags.SESSION_PIECE_COLOR, Piece.Color.WHITE.toString());

        }
        else if (hasUserJoinedTheGame(tableName, userId)) {
            map.put(Tags.GAME_TABLE_NAME, tableName);
            map.put(Tags.SESSION_PIECE_COLOR, Piece.Color.BLACK.toString());
        }
        else {
            throw new RequestNotAllowedException();
        }
        return new View(map, WebPages.GAME, configuration);
    }

    public long getRemainingTime(String tableName) {

        long res = gameManager.getRemainingTime(tableName);

        return res;

    }

    private boolean isGuest(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String userId = getSessionUserId(request);
        if (userId != null)
            if (!isGuestId(userId))
                return false;
        return true;
    }

    private String getSessionUserId(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String userId = (String) session.getAttribute(SessionAttributes.USER_ID);
        return userId;
    }

    private String getSessionTableName(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String gameTableName = (String) session.getAttribute(SessionAttributes.CREATED_GAME_TABLE_NAME);
        return gameTableName;
    }

    private void addToSessionJoinedGameTables(String gameTableName, HttpServletRequest request) {
        HttpSession session = request.getSession();
        LinkedList<String> joinedTableNames = (LinkedList<String>) session.getAttribute(SessionAttributes.JOINED_GAME_TABLE_NAMES);
        if (joinedTableNames == null) {
            joinedTableNames = new LinkedList<String>();

        }
        joinedTableNames.add(gameTableName);
        session.setAttribute(SessionAttributes.JOINED_GAME_TABLE_NAMES, joinedTableNames);

    }

    private boolean hasUserJoinedTheGame(String gameTableName, String userId) {

        Game game = gameManager.getGameTableByName(gameTableName);
        if (game.getPlayer2().getId().equals(userId))
            return true;
        return false;


    }

    private boolean isUserGameCreator(String tableName, HttpServletRequest request) {
        String userId = getSessionUserId(request);

        Game game = gameManager.getGameTableByName(tableName);
        if (game.getPlayer1().getId().equals(userId))
            return true;
        return false;

    }

    private boolean isGuestId(String userId) {
        if (userId.length() <= SessionAttributes.GUEST_ID.length()) {
            return false;
        }
        String temp = userId.substring(0, SessionAttributes.GUEST_ID.length());
        if (temp.equals(SessionAttributes.GUEST_ID))
            return true;
        return false;
    }
}
